﻿using Microsoft.Extensions.Caching.Memory;

namespace StarsAdmin.Core.Helpers
{
    public class CacheHelper
    {
        private static readonly IMemoryCache _cache;

        public CacheHelper(IMemoryCache cache)
        {
            //_cache = cache ?? throw new ArgumentNullException(nameof(cache));
        }

        /// <summary>
        /// 添加数据到本地缓存
        /// </summary>
        /// <param name="key">秘钥键</param>
        /// <param name="value">需要缓存的数据</param>
        /// <exception cref="ArgumentNullException"></exception>
        public static void Set(string key, object value)
        {
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (_cache.TryGetValue(key, out _))
            {
                _cache.Remove(key);
            }
            _cache.Set(key, value);
        }

        /// <summary>
        /// 添加数据到本地缓存
        /// </summary>
        /// <param name="key">秘钥键</param>
        /// <param name="value">缓存值</param>
        /// <param name="expire">过期时间(分钟)</param>
        /// <exception cref="ArgumentNullException"></exception>
        public void Set(string key, object value, int expire)
        {
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (_cache.TryGetValue(key, out _))
            {
                _cache.Remove(key);
            }
            _cache.Set(key, value, TimeSpan.FromSeconds(expire));
        }

        /// <summary>
        /// 添加数据到本地缓存
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="type">数据类别</param>
        /// <param name="value">缓存值</param>
        /// <exception cref="ArgumentNullException"></exception>
        public void Set(long userId, string type, object value)
        {
            string key = $"{type}_{userId}";

            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (_cache.TryGetValue(key, out _))
            {
                _cache.Remove(key);
            }
            _cache.Set(key, value);
        }

        /// <summary>
        /// 添加数据到本地缓存
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="type">数据类别</param>
        /// <param name="value">缓存值</param>
        /// <param name="expire">过期时间(分钟)</param>
        /// <exception cref="ArgumentNullException"></exception>
        public void Set(long userId, string type, object value, int expire)
        {
            string key = $"{type}_{userId}";

            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (_cache.TryGetValue(key, out _))
            {
                _cache.Remove(key);
            }
            _cache.Set(key, value, TimeSpan.FromMinutes(expire));
        }

        /// <summary>
        /// 获得本地缓存中的数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="userId">用户Id</param>
        /// <param name="type">数据类别</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public T Get<T>(long userId, string type)
        {
            string key = $"{type}_{userId}";
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            T value;
            _cache.TryGetValue(key, out value);
            return value;
        }

        /// <summary>
        /// 获得本地缓存中的数据
        /// </summary>
        /// <typeparam name="T">返回值类型</typeparam>
        /// <param name="key">秘钥键</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public T Get<T>(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            T value;
            _cache.TryGetValue(key, out value);
            return value;
        }

        /// <summary>
        /// 尝试获得指定键的值
        /// </summary>
        /// <param name="key">秘钥键</param>
        /// <param name="value">获得的返回值</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public bool TryGetValue(string key, out object? value)
        {
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (_cache.TryGetValue(key, out value))
            {
                return true;
            }
            return false;
        }

        /// <summary>
        ///  验证数据是否存在
        /// </summary>
        /// <param name="key">秘钥键</param>
        /// <param name="value">需要验证的数据</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public bool Validate(string key, string value)
        {
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            string result;
            if (_cache.TryGetValue(key, out result))
            {
                if (result == value)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 验证数据是否存在
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="type">数据类别</param>
        /// <param name="value">需要验证的数据</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public bool Validate(long userId, string type, string value)
        {
            string key = $"{type}_{userId}";
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            string result;
            if (_cache.TryGetValue(key, out result))
            {
                if (result == value)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 移除指定键的数据
        /// </summary>
        /// <param name="key">秘钥键</param>
        /// <exception cref="ArgumentNullException"></exception>
        public void Remove(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            _cache.Remove(key);
        }

        /// <summary>
        /// 移除指定的数据
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="type">数据类别</param>
        /// <exception cref="ArgumentNullException"></exception>
        public void Remove(long userId, string type)
        {
            string key = $"{type}_{userId}";
            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            _cache.Remove(key);
        }
    }
}